package com.wcpdoc.exam.core.dao.impl;

import com.wcpdoc.core.dao.impl.RBaseDaoImpl;
import com.wcpdoc.core.entity.PageIn;
import com.wcpdoc.core.entity.PageOut;
import com.wcpdoc.core.util.DateUtil;
import com.wcpdoc.core.util.HibernateUtil;
import com.wcpdoc.core.util.SqlUtil;
import com.wcpdoc.core.util.SqlUtil.Order;
import com.wcpdoc.core.util.ValidateUtil;
import com.wcpdoc.exam.core.dao.MyMockExamDao;
import com.wcpdoc.exam.core.entity.Exam;
import com.wcpdoc.exam.core.entity.MyMockExam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 我的考试数据访问层实现
 * <p>
 * v1.0 zhanghc 2017-06-19 16:28:29
 */
@Repository
public class MyMockExamDaoImpl extends RBaseDaoImpl<MyMockExam> implements MyMockExamDao {
    private static final Logger log = LoggerFactory.getLogger(MyMockExamDaoImpl.class);

    @Override
    public PageOut getListpage(PageIn pageIn) {
	/*	String sql = "SELECT EXAM.ID AS EXAM_ID, EXAM.NAME AS EXAM_NAME, EXAM.START_TIME AS EXAM_START_TIME, EXAM.END_TIME AS EXAM_END_TIME, "// 考试相关字段
				+ "EXAM.MARK_START_TIME AS EXAM_MARK_START_TIME, EXAM.MARK_END_TIME AS EXAM_MARK_END_TIME, EXAM.MARK_STATE AS EXAM_MARK_STATE, "// 考试相关字段
				+ "EXAM.SCORE_STATE AS EXAM_SCORE_STATE, EXAM.RANK_STATE AS EXAM_RANK_STATE, "// 考试相关字段（用于控制是否显示成绩和排名，控制层用）
				+ "EXAM.TOTAL_SCORE AS EXAM_TOTAL_SCORE, EXAM.PASS_SCORE AS EXAM_PASS_SCORE, "// 考试相关字段
				+ "USER.ID AS USER_ID, USER.NAME AS USER_NAME, "// 考试用户字段
				+ "MY_EXAM.ANSWER_START_TIME, MY_EXAM.ANSWER_END_TIME, MY_EXAM.TOTAL_SCORE, MY_EXAM.STATE, "// 我的考试字段
				+ "MY_EXAM.MARK_STATE, MY_EXAM.ANSWER_STATE, MY_EXAM.NO, "// 我的考试字段
				+ "(SELECT COUNT(1) FROM EXM_MY_MOCK_EXAM A WHERE A.EXAM_ID = MY_EXAM.EXAM_ID) AS USER_NUM "// 用户数量（排名使用）
				+ "FROM EXM_MY_MOCK_EXAM MY_EXAM "
				+ "INNER JOIN EXM_MOCK_EXAM EXAM ON MY_EXAM.EXAM_ID = EXAM.ID "
				+ "LEFT JOIN SYS_USER USER ON MY_MOCK_EXAM.USER_ID = USER.ID "
				+ "LEFT JOIN SYS_USER MARK_USER ON MY_EXAM.MARK_USER_ID = MARK_USER.ID ";

		SqlUtil sqlUtil = new SqlUtil(sql);
		sqlUtil.addWhere(ValidateUtil.isValid(pageIn.get("examName")), "EXAM.NAME LIKE :NAME", "%" + pageIn.get("examName") + "%")
				.addWhere(pageIn.get("curUserId", Integer.class) != null, "MY_EXAM.USER_ID = :USER_ID", pageIn.get("curUserId", Integer.class))
				.addWhere(ValidateUtil.isValid(pageIn.get("startTime")) && ValidateUtil.isValid(pageIn.get("endTime")),
						"(( :START_TIME1 <= EXAM.START_TIME AND EXAM.START_TIME <= :END_TIME1) "
						+ "	OR ( :START_TIME2 <= EXAM.END_TIME AND EXAM.END_TIME <= :END_TIME2) "
						+ "	OR ( :START_TIME3 >= EXAM.START_TIME AND EXAM.END_TIME >= :END_TIME3))",
						pageIn.get("startTime"), pageIn.get("endTime"),
						pageIn.get("startTime"), pageIn.get("endTime"),
						pageIn.get("startTime"), pageIn.get("endTime")
						)
				.addWhere("true".equals(pageIn.get("todo")), // 查找我的未完成的考试列表
						"((MY_EXAM.STATE = 1 AND MY_EXAM.MARK_STATE != 3) OR MY_EXAM.STATE = 2)")
				.addWhere("EXAM.STATE = 1")// 已发布（不含冻结）
				.addOrder("EXAM.START_TIME", Order.DESC);// 按考试开始时间倒序排列
		PageOut pageOut = getListpage(sqlUtil, pageIn);
		HibernateUtil.formatDate(pageOut.getList(),
				"examStartTime", DateUtil.FORMAT_DATE_TIME,
				"examEndTime", DateUtil.FORMAT_DATE_TIME,
				"examMarkEndTime", DateUtil.FORMAT_DATE_TIME,
				"examMarkStartTime", DateUtil.FORMAT_DATE_TIME,
				"answerStartTime", DateUtil.FORMAT_DATE_TIME,
				"answerEndTime", DateUtil.FORMAT_DATE_TIME);*/

/*		String sql = " SELECT EXAM.ID, EXAM.NAME, EXAM.START_TIME, EXAM.END_TIME,  " +
				"                EXAM.PASS_SCORE, EXAM.TOTAL_SCORE, EXAM.STATE,   " +
				"                EXAM.SCORE_STATE, EXAM.UPDATE_TIME," +
				"                 EXAM.GEN_TYPE,EXAM.SXES,   " +
				"               (SELECT COUNT(*) FROM EXM_MY_MOCK_EXAM A WHERE A.EXAM_ID = EXAM.ID) AS USER_NUM " +
				"                FROM EXM_MY_MOCK_EXAM EXAM ";
		SqlUtil sqlUtil = new SqlUtil(sql);
		sqlUtil.addWhere("EXAM.STATE = 1")
				.addWhere(pageIn.get("curUserId", Integer.class) != null, "EXAM.USER_ID = :USER_ID", pageIn.get("curUserId", Integer.class))
				.addWhere(ValidateUtil.isValid(pageIn.get("name")), "EXAM.NAME LIKE :NAME", String.format("%%%s%%", pageIn.get("name")));
//                .addOrder("EXAM.UPDATE_TIME", Order.DESC);
		PageOut pageOut = getListpage(sqlUtil, pageIn);
		return pageOut;*/
        String sql = "SELECT EXAM.ID AS EXAM_ID, EXAM.NAME AS EXAM_NAME, EXAM.START_TIME AS EXAM_START_TIME, EXAM.END_TIME AS EXAM_END_TIME, "// 考试相关字段
                + "EXAM.MARK_START_TIME AS EXAM_MARK_START_TIME, EXAM.MARK_END_TIME AS EXAM_MARK_END_TIME, EXAM.MARK_STATE AS EXAM_MARK_STATE, "// 考试相关字段
                + "EXAM.SCORE_STATE AS EXAM_SCORE_STATE, EXAM.RANK_STATE AS EXAM_RANK_STATE, "// 考试相关字段（用于控制是否显示成绩和排名，控制层用）
                + "EXAM.TOTAL_SCORE AS EXAM_TOTAL_SCORE, EXAM.PASS_SCORE AS EXAM_PASS_SCORE, "// 考试相关字段
                + "USER.ID AS USER_ID, USER.NAME AS USER_NAME, "// 考试用户字段
                + "MY_EXAM.ANSWER_START_TIME, MY_EXAM.ANSWER_END_TIME, MY_EXAM.TOTAL_SCORE, MY_EXAM.STATE, "// 我的考试字段
                + "MY_EXAM.MARK_STATE, MY_EXAM.ANSWER_STATE, MY_EXAM.NO, "// 我的考试字段
                + "(SELECT COUNT(1) FROM EXM_MY_EXAM A WHERE A.EXAM_ID = MY_EXAM.EXAM_ID) AS USER_NUM "// 用户数量（排名使用）
                + "FROM EXM_MY_MOCK_EXAM MY_EXAM "
                + "INNER JOIN EXM_MOCK_EXAM EXAM ON MY_EXAM.EXAM_ID = EXAM.ID "
                + "LEFT JOIN SYS_USER USER ON MY_EXAM.USER_ID = USER.ID "
                + "LEFT JOIN SYS_USER MARK_USER ON MY_EXAM.MARK_USER_ID = MARK_USER.ID ";

        SqlUtil sqlUtil = new SqlUtil(sql);
        sqlUtil.addWhere(ValidateUtil.isValid(pageIn.get("examName")), "EXAM.NAME LIKE :NAME", "%" + pageIn.get("examName") + "%")
                .addWhere(pageIn.get("curUserId", Integer.class) != null, "MY_EXAM.USER_ID = :USER_ID", pageIn.get("curUserId", Integer.class))
                .addWhere(ValidateUtil.isValid(pageIn.get("startTime")) && ValidateUtil.isValid(pageIn.get("endTime")),
                        "(( :START_TIME1 <= EXAM.START_TIME AND EXAM.START_TIME <= :END_TIME1) "
                                + "	OR ( :START_TIME2 <= EXAM.END_TIME AND EXAM.END_TIME <= :END_TIME2) "
                                + "	OR ( :START_TIME3 >= EXAM.START_TIME AND EXAM.END_TIME >= :END_TIME3))",
                        pageIn.get("startTime"), pageIn.get("endTime"),
                        pageIn.get("startTime"), pageIn.get("endTime"),
                        pageIn.get("startTime"), pageIn.get("endTime")
                )
                .addWhere("true".equals(pageIn.get("todo")), // 查找我的未完成的考试列表
                        "((MY_EXAM.STATE = 1 AND MY_EXAM.MARK_STATE != 3) OR MY_EXAM.STATE = 2)")
                .addWhere("EXAM.STATE = 1")// 已发布（不含冻结）
                .addOrder("EXAM.START_TIME", Order.DESC);// 按考试开始时间倒序排列
        PageOut pageOut = getListpage(sqlUtil, pageIn);
        HibernateUtil.formatDate(pageOut.getList(),
                "examStartTime", DateUtil.FORMAT_DATE_TIME,
                "examEndTime", DateUtil.FORMAT_DATE_TIME,
                "examMarkEndTime", DateUtil.FORMAT_DATE_TIME,
                "examMarkStartTime", DateUtil.FORMAT_DATE_TIME,
                "answerStartTime", DateUtil.FORMAT_DATE_TIME,
                "answerEndTime", DateUtil.FORMAT_DATE_TIME);
        return pageOut;
    }

    @Override
    public List<Map<String, Object>> getListUser(String id) {
        return null;
    }

    @Override
    public List<MyMockExam> getList(Integer examId) {
        String sql = "SELECT * FROM EXM_MY_MOCK_EXAM WHERE EXAM_ID = :EXAM_ID";
        log.info("=====考试人数");
        log.info("=====考试人数" + examId);
        return getList(sql, new Object[]{examId}, MyMockExam.class);
    }

    @Override
    public List<MyMockExam> getListForUser(Integer userId) {
        String sql = "SELECT * FROM EXM_MY_MOCK_EXAM WHERE USER_ID = :USER_ID";
        return getList(sql, new Object[]{userId}, MyMockExam.class);
    }

    @Override
    public MyMockExam getMyExam(Integer examId, Integer userId) {
        String sql = "SELECT * FROM EXM_MY_MOCK_EXAM WHERE EXAM_ID = :EXAM_ID AND USER_ID = :USER_ID";
        return getEntity(sql, new Object[]{examId, userId});
    }

    @Override
    public List<MyMockExam> getExamList(Integer userId) {
        String sql = "SELECT EXAM.* "
                + "FROM EXM_MOCK_EXAM EXAM "
                + "WHERE EXAM.STATE != 0 "
                + "	AND EXISTS (SELECT 1 FROM EXM_MY_MOCK_EXAM Z WHERE Z.USER_ID = :USER_ID AND EXAM.ID = Z.EXAM_ID) ";
        return getList(sql, new Object[]{userId}, MyMockExam.class);
    }

    @Override
    public void clear(Integer examId) {
        String sql = "DELETE FROM EXM_MY_MOCK_EXAM WHERE EXAM_ID = :EXAM_ID";
        update(sql, new Object[]{examId});
    }

    @Override
//    后期应废弃
    public void clearAnswer(Integer examId, Integer userId) {

//        大致思路：首次考试，那么成绩肯定为0 ，就保留，下次再考试时，如果这个分数低于之前的，就保留之前的，反之，则更新为最高的
        String sql = "UPDATE EXM_MY_MOCK_EXAM  " +
                "SET " +
//                "TOTAL_SCORE = :TOTAL_SCORE , " +
//                " OBJECTIVE_SCORE =NULL, " +
//                " ANSWER_STATE = NULL, " +
                " MARK_USER_ID=NULL, " +
//                " ANSWER_START_TIME = NULL, " +
//                " ANSWER_END_TIME = NULL, " +
//                " MARK_END_TIME = NULL," +
//                " MARK_START_TIME = NULL, " +
                " STATE = 3 " +
//                " MARK_STATE =  1 " +
                " WHERE EXAM_ID = :EXAM_ID AND USER_ID = :USER_ID";
        update(sql, new Object[]{  examId, userId});
    }
}
